<template>
  <div class="cc-calendar">
    <calendarHeader
      :headOptions="headOptions"
      @handlePrevMonth="handlePrevMonth"
      @handleNextMonth="handleNextMonth"
      @handleToday="handleToday"
    />
    <ul class="calendar-week clear">
      <li
        v-for="(item, index) in calendarTitleArr"
        :key="index"
        class="week-item"
      >
        {{ item.title[language] }}
      </li>
    </ul>
    <ul class="calendar-view clear">
      <li
        v-for="(item, index) in visibleCalendar"
        :key="index"
        class="date-view"
        :class="[
          { 'month-class': !isCurrentMonth(item.date) },
          { todayBg: isCurrentDay(item.date) },
          {
            handleDay:
              selectedRows.findIndex((e) => e.dateString === item.dateString) >
              -1,
          },
        ]"
        @click="
          handleClickDay({
            task: resources.filter(
              (e) =>
                moment(e.date).format('YYYY-MM-DD') ==
                moment(item.date).format('YYYY-MM-DD')
            ),
            ...item,
          })
        "
      >
        <span
          class="date-day"
          :style="dayStyle"
          :class="[{ 'opacity-class': !isCurrentMonth(item.date) }]"
        >
          {{ item.day }}
        </span>

        <!-- 渲染插槽 -->
        <slot
          name="resourcesBody"
          v-bind="{
            task: resources.filter(
              (e) =>
                moment(e.date).format('YYYY-MM-DD') ==
                moment(item.date).format('YYYY-MM-DD')
            ),
            ...item,
          }"
          v-if="
            resources.findIndex(
              (e) =>
                moment(e.date).format('YYYY-MM-DD') ==
                moment(item.date).format('YYYY-MM-DD')
            ) != -1
          "
        />
      </li>
    </ul>
  </div>
</template>

<script>
import "../assets/css/reset.min.css";
import calendarHeader from "./canlendar-head.vue";
import * as utils from "../assets/js/utils.js";
import moment from "moment";

export default {
  name: "cc-calendar",
  componentName: "cc-calendar",
  props: {
    options: Object,
    /** 渲染数据 */
    resources: {
      type: Array,
    },
    /** 是否支持多选 */
    isMultiple: {
      type: Boolean,
      default: () => false,
    },
  },
  components: {
    calendarHeader,
  },
  data() {
    let { year, month, day } = utils.getNewDate(new Date());
    return {
      /** 设置第一天显示周几
       *  默认：周日.0
       *  参数：周日.0 周一.1 以此内推...
       */
      defaultFirstDay: 0,
      /** 日历语言
       *  默认 CH 简体中文
       */
      language: "CH",
      headOptions: {
        type: this.options.type,
        style: this.options.headStyle,
        date: "",
      },
      time: { year, month, day },
      calendarList: [],
      /** 选中的日期
       *  默认单选
       */
      selectedRows: [],
    };
  },
  computed: {
    dayStyle: function () {
      return {
        textAlign: this.options.viewStyle.day,
      };
    },
    calendarTitleArr() {
      let initTitle = [
        { title: { CH: "星期一", US: "MON" }, key: 1 },
        { title: { CH: "星期二", US: "TUE" }, key: 2 },
        { title: { CH: "星期三", US: "WED" }, key: 3 },
        { title: { CH: "星期四", US: "THU" }, key: 4 },
        { title: { CH: "星期五", US: "FRI" }, key: 5 },
        { title: { CH: "星期六", US: "SAT" }, key: 6 },
        { title: { CH: "星期日", US: "SUN" }, key: 0 },
      ];
      /** 默认一周第一天显示星期几 之前的数据存放 */
      let inArr = [];
      let puArr = [];

      let finObjIndex = initTitle.findIndex(
        (e) => e.key === this.defaultFirstDay
      );

      if (finObjIndex != -1) {
        /** 先将一周第一天星期几放在最前面 */
        for (let index = finObjIndex; index < initTitle.length; index++) {
          inArr.push(initTitle[index]);
        }
        /** 再将后面的星期跟随 */
        for (let index = finObjIndex - 1; index >= 0; index--) {
          puArr.unshift(initTitle[index]);
        }
      }
      return inArr.concat(puArr);
    },
    visibleCalendar() {
      let calendatArr = [];
      let { year, month, day } = utils.getNewDate(
        utils.getDate(this.time.year, this.time.month, 1)
      );

      let currentFirstDay = utils.getDate(year, month, 1);

      // 获取当前月第一天星期几
      let weekDay = currentFirstDay.getDay();

      /** 头部星期栏中的 第一天在第几个 */
      let hTitleIndex = this.calendarTitleArr.findIndex(
        (e) => e.key === weekDay
      );
      let startTime = currentFirstDay - hTitleIndex * 24 * 60 * 60 * 1000;

      /** 获取本月一共有几天 */
      let total = new Date(year, month + 1, 0).toLocaleDateString();
      let monthDayNum;
      if (
        (hTitleIndex == 5 &&
          total.split("/")[total.split("/").length - 1] > 31) ||
        hTitleIndex == 6
      ) {
        monthDayNum = 42;
      } else {
        monthDayNum = 35;
      }

      for (let i = 0; i < monthDayNum; i++) {
        calendatArr.push({
          date: new Date(startTime + i * 24 * 60 * 60 * 1000),
          dateString: moment(
            new Date(startTime + i * 24 * 60 * 60 * 1000)
          ).format("YYYY-MM-DD"),
          year: year,
          month: month + 1,
          day: new Date(startTime + i * 24 * 60 * 60 * 1000).getDate(),
          clickDay: false,
        });
      }

      this.headOptions.date = `${utils.englishMonth(
        month,
        this.language
      )} ${year}`;
      return calendatArr;
    },
  },
  methods: {
    moment,
    // 是否是当前月
    isCurrentMonth(date) {
      let { year: currentYear, month: currentMonth } = utils.getNewDate(
        utils.getDate(this.time.year, this.time.month, 1)
      );
      let { year, month } = utils.getNewDate(date);
      return currentYear == year && currentMonth == month;
    },
    // 是否是今天
    isCurrentDay(date) {
      let {
        year: currentYear,
        month: currentMonth,
        day: currentDay,
      } = utils.getNewDate(new Date());
      let { year, month, day } = utils.getNewDate(date);
      return currentYear == year && currentMonth == month && currentDay == day;
    },
    // 上一个月
    handlePrevMonth() {
      let prevMonth = utils.getDate(this.time.year, this.time.month, 1);
      prevMonth.setMonth(prevMonth.getMonth() - 1);
      this.time = utils.getNewDate(prevMonth);
      this.headOptions.date = `${utils.englishMonth(
        this.time.month,
        this.language
      )} ${this.time.year}`;
      this.$emit("handlePrevMonth");
    },
    // 下一个月
    handleNextMonth() {
      let nextMonth = utils.getDate(this.time.year, this.time.month, 1);
      nextMonth.setMonth(nextMonth.getMonth() + 1);
      this.time = utils.getNewDate(nextMonth);
      this.headOptions.date = `${utils.englishMonth(
        this.time.month,
        this.language
      )} ${this.time.year}`;
      this.$emit("handleNextMonth");
    },
    // 点击回到今天
    handleToday() {
      this.time = utils.getNewDate(new Date());
      this.$emit("handleToday");
    },
    // 点击某一天
    handleClickDay(item) {
      this.$forceUpdate();
      this.$emit("handleClickDay", item);
      let findIndex = this.selectedRows.findIndex(
        (e) => e.dateString === item.dateString
      );
      if (findIndex > -1) {
        this.selectedRows.splice(findIndex, 1);
      } else {
        /** 如果支持多选将push 否则代替 */
        if (this.isMultiple) {
          this.selectedRows.push(item);
        } else {
          this.selectedRows = [item];
        }
      }
    },
  },
  created() {
    this.calendarList = this.visibleCalendar;
    this.calendarType = this.options.calendarType;
  },
};
</script>

<style lang="less">
.cc-calendar {
  padding: 23px 30px 30px;
  width: 100%;
  height: 100%;
  background: #f9fafc;
  box-sizing: border-box;
  .calendar-week {
    width: 100%;
    height: 46px;
    line-height: 46px;
    border: 1px solid #e4e7ea;
    border-right: none;
    border-bottom: none;

    .week-item {
      float: left;
      width: 14.285%;
      text-align: center;
      font-size: 14px;
      color: #424953;
      border-right: 1px solid #e4e7ea;
      font-weight: 600;
    }
  }
  .calendar-view {
    width: 100%;
    border-left: 1px solid #e4e7ea;
    .date-view {
      // float: left;
      // width: 14.285%;
      // height: 120px;
      // border-right: 1px solid #e4e7ea;
      // border-bottom: 1px solid #e4e7ea;
      // cursor: pointer;
      float: left;
      width: 14.285%;
      height: 150px;
      border-right: 1px solid #e4e7ea;
      border-top: 2px solid #e4e7ea;
      cursor: pointer;

      &:hover {
        background-color: #e6f7ff;
        .date-day {
          color: #bccfff !important;
        }
      }

      &:nth-last-child(-n + 7) {
        border-bottom: 2px solid #e4e7ea;
      }

      .date-day {
        padding: 8px 8px 0;
        display: block;
        width: 100%;
        font-size: 14px;
        color: #7f8794;
      }
      .calendar-num {
        margin-top: 6px;
        display: block;
        width: 100%;
        text-align: center;
        font-size: 30px;
        color: #424953;
      }
    }
    .opacity-class {
      opacity: 0.5;
    }
    .month-class {
      background-image: linear-gradient(
        45deg,
        rgba(000, 000, 000, 0.03) 25%,
        transparent 25%,
        transparent 50%,
        rgba(000, 000, 000, 0.03) 50%,
        rgba(000, 000, 000, 0.03) 75%,
        transparent 75%,
        transparent
      );
      background-size: 20px 20px;

      &:hover {
        background-image: linear-gradient(
          45deg,
          rgba(188, 207, 255, 0.3) 25%,
          transparent 25%,
          transparent 50%,
          rgba(188, 207, 255, 0.3) 50%,
          rgba(188, 207, 255, 0.3) 75%,
          transparent 75%,
          transparent
        ) !important;
      }
    }
    .todayBg {
      background: #e6f7ff;
      border-top-color: #1890ff;
    }
    .handleDay {
      background: #e6f7ff !important;
      .date-day {
        color: #bccfff !important;
      }
      .calendar-num {
        color: #fff !important;
      }
    }
  }
}
</style>